
#include "dma.h"
#include <stdio.h>
#include "bsp_init.h"
#include "hc32_ll.h"
#include "hc32_ll_clk.h"
#include "hc32_ll_utility.h"
#include "hc32_ll_usart.h"
#include <string.h> 
#include "hc32_common.h"
#include "hc32_ll_aos.h"

#define RXBUF_LEN 512
#define TXBUF_LEN 512

#define RX3BUF_LEN 512
#define TX3BUF_LEN 512

uint8_t uart1sendBuf[TXBUF_LEN];
uint8_t uart1recvBuf[RXBUF_LEN];
const uint8_t * const g_uart1rx = uart1recvBuf;

uint8_t uart3sendBuf[TX3BUF_LEN];
uint8_t uart3recvBuf[RX3BUF_LEN];
const uint8_t * const g_uart3rx = uart3recvBuf;


#define USART1_UNIT				(CM_USART1)
#define USART3_UNIT				(CM_USART3)

/**************************DMA1*******************************/ 
#define DMA1_UNIT				(CM_DMA1)
#define DMA1_CH_RX				(DMA_CH2)
#define DMA1_CH_TX				(DMA_CH3)
#define DMA1_TRG_SEL_RX			(EVT_SRC_USART1_RI)
#define DMA1_TRG_SEL_TX			(EVT_SRC_USART1_TI)
///dmaipr*
#define TX_DMA1_TC_INT_SRC               (INT_SRC_DMA1_TC3)
#define TX_DMA1_TC_IRQn                  (INT004_IRQn)
#define TX_DMA1_TRIG_SEL                 (AOS_DMA1_3)
#define TX_DMA1_TRIG_EVT_SRC             (EVT_SRC_USART1_TI)
#define TX_DMA1_TC_INT                   (DMA_INT_TC_CH3)
#define TX_DMA1_TC_FLAG                  (DMA_FLAG_TC_CH3)
/****************************DMA2****************************/ 
#define DMA2_UNIT				(CM_DMA2)
#define DMA2_CH_RX				(DMA_CH0)
#define DMA2_CH_TX				(DMA_CH1)
#define DMA2_TRG_SEL_RX			(EVT_SRC_USART3_RI)
#define DMA2_TRG_SEL_TX			(EVT_SRC_USART3_TI)
///dmaipr*
#define TX_DMA_TC_INT_SRC               (INT_SRC_DMA2_TC1)
#define TX_DMA_TC_IRQn                  (INT001_IRQn)
#define TX_DMA_TRIG_SEL                 (AOS_DMA2_1)
#define TX_DMA_TRIG_EVT_SRC             (EVT_SRC_USART3_TI)
#define TX_DMA_TC_INT                   (DMA_INT_TC_CH1)
#define TX_DMA_TC_FLAG                  (DMA_FLAG_TC_CH1)
/*************************************************************/

/**
 * @brief  DMA transfer complete IRQ callback function.
 * @param  None
 * @retval None
 */
static void TX_DMA1_TC_IrqCallback(void)
{
    USART_FuncCmd(USART1_UNIT, USART_INT_TX_CPLT, ENABLE);
    DMA_ClearTransCompleteStatus(DMA1_UNIT, TX_DMA1_TC_FLAG);
}

void Dma1Init(void)
{
	int32_t i32Ret;
	stc_dma_init_t stcDmaInit;
	stc_irq_signin_config_t stcIrqSignConfig;
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA1 | FCG0_PERIPH_DMA2,ENABLE);
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    /* 	Enable DMA.	*/
    //DMA_Cmd(DMA1_UNIT,ENABLE);
								
    //接收						
    /* 	Initialize DMA. 	*/	
    MEM_ZERO_STRUCT(stcDmaInit);
	stcDmaInit.u32BlockSize   = 1u;//0x01UL;
	//stcDmaInit.u32TransCount  = 10u;//0x00UL;
	stcDmaInit.u32SrcAddr     = ((uint32_t)(&USART1_UNIT->DR)+2ul);
	stcDmaInit.u32DestAddr    = (uint32_t)(uart1recvBuf);
	stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_FIX;
	stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;
	stcDmaInit.u32IntEn       = DMA_INT_DISABLE;
	stcDmaInit.u32DataWidth   = DMA_DATAWIDTH_8BIT;
	DMA_Init(DMA1_UNIT, DMA1_CH_RX, &stcDmaInit);
	/***dma重复发送、接收模式配置（这里是分开配置的）***/
	stc_dma_repeat_init_t	stcDmaRepeatInit;
    MEM_ZERO_STRUCT(stcDmaRepeatInit);  
	DMA_RepeatStructInit(&stcDmaRepeatInit);
	DMA_RepeatInit(DMA1_UNIT,DMA1_CH_RX,&stcDmaRepeatInit);
	/**********end************/
	DMA_ChCmd(DMA1_UNIT, DMA1_CH_RX, ENABLE);
    /* Enable peripheral circuit trigger function. */
	FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS,ENABLE);
    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(DMA1_UNIT, DMA1_CH_RX, DMA1_TRG_SEL_RX);

    //发送 
    /* Initialize DMA. */
    MEM_ZERO_STRUCT(stcDmaInit);
	stcDmaInit.u32BlockSize   = 1u;//0x01UL;
//	stcDmaInit.u32TransCount  = 1u;//0x00UL;
	stcDmaInit.u32SrcAddr     = (uint32_t)(uart1sendBuf);
	stcDmaInit.u32DestAddr    = (uint32_t)(&USART1_UNIT->DR);     /* Set destination address. */
	stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
	stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX;
	stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
	stcDmaInit.u32DataWidth   = DMA_DATAWIDTH_8BIT;
    i32Ret=DMA_Init(DMA1_UNIT, DMA1_CH_TX, &stcDmaInit); 
	
    if (LL_OK == i32Ret) 
	{
        stcIrqSignConfig.enIntSrc = TX_DMA1_TC_INT_SRC;
        stcIrqSignConfig.enIRQn  = TX_DMA1_TC_IRQn;
        stcIrqSignConfig.pfnCallback = &TX_DMA1_TC_IrqCallback;
        (void)INTC_IrqSignIn(&stcIrqSignConfig);
        NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
        NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
        NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
		
        AOS_SetTriggerEventSrc(TX_DMA1_TRIG_SEL, TX_DMA1_TRIG_EVT_SRC);
		
        DMA_Cmd(DMA1_UNIT, ENABLE);
        DMA_TransCompleteIntCmd(DMA1_UNIT, TX_DMA1_TC_INT, ENABLE);
    }
    /* Enable the specified DMA channel. */
    // DMA_ChannelCmd(DMA_UNIT, DMA_CH_TX, Enable);
    /* Clear DMA flag. */
    // DMA_ClearIrqFlag(DMA_UNIT, DMA_CH_TX, TrnCpltIrq);
    /* Set DMA trigger source. */
    //DMA_SetTriggerSrc(DMA1_UNIT, DMA1_CH_TX, DMA1_TRG_SEL_TX);
}
/**
 * @brief  DMA transfer complete IRQ callback function.
 * @param  None
 * @retval None
 */
static void TX_DMA_TC_IrqCallback(void)
{
    USART_FuncCmd(USART3_UNIT, USART_INT_TX_CPLT, ENABLE);
    DMA_ClearTransCompleteStatus(DMA2_UNIT, TX_DMA_TC_FLAG);
}

void Dma2Init(void)
{
	int32_t i32Ret;
	stc_dma_init_t stcDmaInit;
	stc_irq_signin_config_t stcIrqSignConfig;
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA1 | FCG0_PERIPH_DMA2,ENABLE);
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
	/* 	Enable DMA.	*/
    //DMA_Cmd(DMA2_UNIT,ENABLE);
								
    //接收						 
    MEM_ZERO_STRUCT(stcDmaInit);  
	stcDmaInit.u32BlockSize   = 1u;//0x01UL;
	//stcDmaInit.u32TransCount  = 10u;//0x00UL;
	stcDmaInit.u32SrcAddr     = ((uint32_t)(&USART3_UNIT->DR)+2ul);
	stcDmaInit.u32DestAddr    = (uint32_t)(uart3recvBuf);
	stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_FIX;
	stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;
	stcDmaInit.u32IntEn       = DMA_INT_DISABLE;
	stcDmaInit.u32DataWidth   = DMA_DATAWIDTH_8BIT;
	DMA_Init(DMA2_UNIT, DMA2_CH_RX, &stcDmaInit);
	/***dma重复发送、接收模式配置（这里是分开配置的）***/
	stc_dma_repeat_init_t	stcDmaRepeatInit;
    MEM_ZERO_STRUCT(stcDmaRepeatInit);  
	DMA_RepeatStructInit(&stcDmaRepeatInit);
	DMA_RepeatInit(DMA2_UNIT,DMA2_CH_RX,&stcDmaRepeatInit);
	/********end**********/
	DMA_ChCmd(DMA2_UNIT, DMA2_CH_RX, ENABLE);
    /* Enable peripheral circuit trigger function. */
	FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS,ENABLE);
    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(DMA2_UNIT, DMA2_CH_RX, DMA2_TRG_SEL_RX);

    //发送  
    MEM_ZERO_STRUCT(stcDmaInit);
	stcDmaInit.u32BlockSize   = 1u;//0x01UL;
 	//stcDmaInit.u32TransCount  = 32u;//0x00UL;
	stcDmaInit.u32SrcAddr     = (uint32_t)(uart3sendBuf);
	stcDmaInit.u32DestAddr    = (uint32_t)(&USART3_UNIT->DR);     /* Set destination address. */
	stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
	stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX;
	stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
	stcDmaInit.u32DataWidth   = DMA_DATAWIDTH_8BIT;
    i32Ret=DMA_Init(DMA2_UNIT, DMA2_CH_TX, &stcDmaInit); 
    if (LL_OK == i32Ret) 
	{
        stcIrqSignConfig.enIntSrc = TX_DMA_TC_INT_SRC;
        stcIrqSignConfig.enIRQn  = TX_DMA_TC_IRQn;
        stcIrqSignConfig.pfnCallback = &TX_DMA_TC_IrqCallback;
        (void)INTC_IrqSignIn(&stcIrqSignConfig);
        NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
        NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
        NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
		
        AOS_SetTriggerEventSrc(TX_DMA_TRIG_SEL, TX_DMA_TRIG_EVT_SRC);
		
        DMA_Cmd(DMA2_UNIT, ENABLE);
        DMA_TransCompleteIntCmd(DMA2_UNIT, TX_DMA_TC_INT, ENABLE);
    }
    //DMA_SetTriggerSrc(DMA2_UNIT, DMA2_CH_TX,DMA2_TRG_SEL_TX);
}

void dmaUart1SendData(uint8_t *data, uint8_t len)
{
	uint8_t sendBuf[TXBUF_LEN];
	//等待数据发送完成
    while(DMA1_UNIT->MONDTCTL1_f.CNT > 0)
    {
        ;
    }
    // 这里还要再延时一下，否则会丢2个左右的数据	
    // 延时时间和波特率有关   						
	DDL_DelayUS(100);								
    USART_FuncCmd(USART1_UNIT, USART_TX, DISABLE);	
    DMA_ChCmd(DMA1_UNIT, DMA1_CH_TX, DISABLE);
    DMA_SetSrcAddr(DMA1_UNIT, DMA1_CH_TX,(uint32_t)sendBuf);
    memcpy(sendBuf,data,len);
    DMA_SetTransCount(DMA1_UNIT, DMA1_CH_TX,len);
    DMA_ChCmd(DMA1_UNIT, DMA1_CH_TX, ENABLE);
    USART_FuncCmd(USART1_UNIT, USART_TX, ENABLE);
}	
	
void dmaUart3SendData(uint8_t *data, uint16_t len)
{
	uint8_t sendBuf[TXBUF_LEN];
    // 等待数据发送完成
    while(DMA2_UNIT->MONDTCTL1_f.CNT > 0)
    {
        ;
    }
    // 这里还要再延时一下，否则会丢2个左右的数据
    // 延时时间和波特率有关
	DDL_DelayUS(100);								
    USART_FuncCmd(USART3_UNIT, USART_TX, DISABLE);	
    DMA_ChCmd(DMA2_UNIT, DMA2_CH_TX, DISABLE);		
    DMA_SetSrcAddr(DMA2_UNIT, DMA2_CH_TX,(uint32_t)sendBuf);
    memcpy(sendBuf,data,len);						
    DMA_SetTransCount(DMA2_UNIT, DMA2_CH_TX,len);	
    DMA_ChCmd(DMA2_UNIT, DMA2_CH_TX, ENABLE);		
    USART_FuncCmd(USART3_UNIT, USART_TX, ENABLE);	
}	
void dma1senddatatransplant(uint8_t *data, uint16_t len)
{
	DMA_SetSrcAddr(DMA1_UNIT, DMA1_CH_TX, (uint32_t)data);
	DMA_SetTransCount(DMA1_UNIT, DMA1_CH_TX, len);
	(void)DMA_ChCmd(DMA1_UNIT, DMA1_CH_TX, ENABLE);
	USART_FuncCmd(USART1_UNIT, USART_TX, ENABLE);
}
void dma3senddatatransplant(uint8_t *data, uint16_t len)
{
	DMA_SetSrcAddr(DMA2_UNIT, DMA2_CH_TX, (uint32_t)data);
	DMA_SetTransCount(DMA2_UNIT, DMA2_CH_TX, len);
	(void)DMA_ChCmd(DMA2_UNIT, DMA2_CH_TX, ENABLE);
	USART_FuncCmd(USART3_UNIT, USART_TX, ENABLE);
}	
uint16_t getUart1RemainRecvBuf(void)
{
    return (RXBUF_LEN - DMA1_UNIT->MONRPT0_f.DRPT);
}

uint16_t getUart3RemainRecvBuf(void)
{
    return (RXBUF_LEN - DMA2_UNIT->MONRPT0_f.DRPT);
}


